﻿using System;
using JetBrains.Annotations;
using MugenMvvmToolkit.Annotations;
using MugenMvvmToolkit.Interfaces.ViewModels;
using MugenMvvmToolkit.Models;

namespace MugenMvvmToolkit.Interfaces
{
    /// <summary>
    ///     Represents the provider which creates a view models.
    /// </summary>
    public interface IViewModelProvider
    {
        /// <summary>
        ///     Creates an instance of the specified view model.
        /// </summary>
        /// <param name="getViewModel">The specified delegate to create view model.</param>
        /// <param name="policy">The specified <see cref="IActivationPolicy" />.</param>
        /// <param name="parentViewModel">The specified parent view model, if any.</param>
        /// <returns>
        ///     An instance of <see cref="IViewModel" />.
        /// </returns>
        [Pure]
        IViewModel GetViewModel([NotNull]GetViewModelDelegate<IViewModel> getViewModel, [CanBeNull] IActivationPolicy policy, [CanBeNull]IViewModel parentViewModel);

        /// <summary>
        ///     Creates an instance of the specified view model.
        /// </summary>
        /// <param name="viewModelType">The type of view model.</param>
        /// <param name="policy">The specified <see cref="IActivationPolicy" />.</param>
        /// <param name="parentViewModel">The specified parent view model, if any.</param>
        /// <returns>
        ///     An instance of <see cref="IViewModel" />.
        /// </returns>
        [Pure]
        IViewModel GetViewModel([NotNull, ViewModelTypeRequired]Type viewModelType, [CanBeNull]IActivationPolicy policy, [CanBeNull] IViewModel parentViewModel);

        /// <summary>
        ///     Initializes specified <see cref="IViewModel" />, use this method if you have created an <see cref="IViewModel" /> without using the GetViewModel method.
        /// </summary>
        /// <param name="viewModel">
        ///     The specified <see cref="IViewModel" />.
        /// </param>
        /// <param name="policy">The specified <see cref="IActivationPolicy" />.</param>
        /// <param name="parentViewModel">The specified parent view model, if any.</param>
        void InitializeViewModel([NotNull]IViewModel viewModel, [CanBeNull]IActivationPolicy policy, [CanBeNull] IViewModel parentViewModel);
    }
}